/*  
 *  Nanjing JIYU Technology Co.,Ltd All rights reserved.
 *  Copyright (C) 2022 
 *  ==============================================================
 * 
 *  timer.c
 *    系统用到的定时器配置
 *
 *  --------------------------------------------------------------
 *  
 */

#include "timer.h"


TIM_HandleTypeDef 	htim2;                   								 //定时器1、5初始化句柄
DMA_HandleTypeDef hdma_tim2_ch1_trig, hdma_tim2_ch2_trig;

void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
  GPIO_InitTypeDef gpio_config;
  
  if (htim->Instance == TIM3)
  {
    __HAL_RCC_TIM3_CLK_ENABLE();
    
    /* 电机PWM引脚初始化  PA6、PA7、PB0、PB1 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    
    gpio_config.Pin = GPIO_PIN_6 | GPIO_PIN_7;
    gpio_config.Mode = GPIO_MODE_AF_PP;
    gpio_config.Pull = GPIO_PULLUP;
    gpio_config.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &gpio_config);

    gpio_config.Pin = GPIO_PIN_0 | GPIO_PIN_1;
    gpio_config.Mode = GPIO_MODE_AF_PP;
    gpio_config.Pull = GPIO_PULLUP;
    gpio_config.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &gpio_config);   
  }
  
  if (htim->Instance == TIM2)
  {
    __HAL_RCC_TIM2_CLK_ENABLE();
    
    /* 电机PWM引脚初始化  PA6、PA7、PB0、PB1 */
    __HAL_RCC_GPIOA_CLK_ENABLE();
    
    gpio_config.Pin = GPIO_PIN_0;
    gpio_config.Mode = GPIO_MODE_AF_PP;
    gpio_config.Pull = GPIO_PULLUP;
    gpio_config.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &gpio_config); 
  }
  
  GPIO_InitTypeDef GPIO_Initure;
  
  if(htim->Instance==TIM2)
  {	
		__HAL_RCC_TIM2_CLK_ENABLE();
		__HAL_RCC_GPIOA_CLK_ENABLE();
		__HAL_RCC_DMA1_CLK_ENABLE();
		
		GPIO_Initure.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_Initure.Mode = GPIO_MODE_AF_PP;
    GPIO_Initure.Pull = GPIO_NOPULL;
    GPIO_Initure.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_Initure);
  
    /* TIM5 DMA Init */
    /* TIM5_CH1_TRIG Init */
    hdma_tim2_ch1_trig.Instance = DMA1_Channel5;
    hdma_tim2_ch1_trig.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_tim2_ch1_trig.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_tim2_ch1_trig.Init.MemInc = DMA_MINC_ENABLE;
    hdma_tim2_ch1_trig.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_tim2_ch1_trig.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_tim2_ch1_trig.Init.Mode = DMA_NORMAL;
    hdma_tim2_ch1_trig.Init.Priority = DMA_PRIORITY_MEDIUM;
    HAL_DMA_Init(&hdma_tim2_ch1_trig);

    /* TIM5 DMA Init */
    /* TIM5_CH2_TRIG Init */
    hdma_tim2_ch2_trig.Instance = DMA1_Channel7;
    hdma_tim2_ch2_trig.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_tim2_ch2_trig.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_tim2_ch2_trig.Init.MemInc = DMA_MINC_ENABLE;
    hdma_tim2_ch2_trig.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_tim2_ch2_trig.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_tim2_ch2_trig.Init.Mode = DMA_NORMAL;
    hdma_tim2_ch2_trig.Init.Priority = DMA_PRIORITY_MEDIUM;
    HAL_DMA_Init(&hdma_tim2_ch2_trig);
		
    /* Several peripheral DMA handle pointers point to the same DMA handle.
     Be aware that there is only one stream to perform all the requested DMAs. */
    __HAL_LINKDMA(htim,hdma[TIM_DMA_ID_CC1],hdma_tim2_ch1_trig);
    __HAL_LINKDMA(htim,hdma[TIM_DMA_ID_TRIGGER],hdma_tim2_ch1_trig);

		__HAL_LINKDMA(htim,hdma[TIM_DMA_ID_CC2],hdma_tim2_ch2_trig);
    __HAL_LINKDMA(htim,hdma[TIM_DMA_ID_TRIGGER],hdma_tim2_ch2_trig);

    /* TIM3 interrupt Init */
    HAL_NVIC_SetPriority(TIM2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM2_IRQn);
    
    /* DMA interrupt init */
    /* DMA1_Stream4_IRQn interrupt configuration */
     HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
		HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);
	}
}

/*-----------------------------  TIM3,用于电机控制  -----------------------------*/

TIM_HandleTypeDef htim3;

static void timer_motor_pwm_init(void)
{
  TIM_OC_InitTypeDef sConfigOC;

  htim3.Instance = TIM3;
  htim3.Init.Period = 1000 - 1;
  htim3.Init.Prescaler = 72 - 1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(&htim3);

  sConfigOC.OCMode = TIM_OCMODE_PWM2;                                   //配置TIM3 CH1为PWM1模式
  sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;                           //输出比较极性为低
//	sConfigOC.Pulse=64;
  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);          //PWM初始化
  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);          //PWM初始化
  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3);          //PWM初始化
  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4);          //PWM初始化

  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);                            //开启定时器3PWM波输出
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);                            //开启定时器3PWM波输出
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);                            //开启定时器3PWM波输出
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_4);                            //开启定时器3PWM波输出
}


/*-----------------------------  TIM6,用于超声波计时  -----------------------------*/

TIM_HandleTypeDef htim6;

static void timer_ultrasonic_init(void)
{
	TIM_MasterConfigTypeDef sMasterConfig;

  htim6.Instance = TIM6;
  htim6.Init.Prescaler = (72-1);   /* 1MHz 1s=1,000,000 1ms=1000 CCR直接读就是us */
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 50000;      /* 50ms 重装，最远测距 8.5米  */
  
  HAL_TIM_Base_Init(&htim6);
    
  __HAL_TIM_DISABLE(&htim6);
  __HAL_TIM_SetCounter(&htim6,0); //把定时器6的计数值清零
}

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
  __HAL_RCC_TIM6_CLK_ENABLE();
}


void timer6_start_count(void)
{
  __HAL_TIM_ENABLE(&htim6);
}

/* 停止计数并返回计数值 */
int timer6_stop_count(void)
{
  int cnt = __HAL_TIM_GetCounter(&htim6);
  __HAL_TIM_DISABLE(&htim6);
  __HAL_TIM_SetCounter(&htim6,0); //把定时器6的计数值清零
  return cnt;
}


/*-----------------------------  TIM2,产生与RGB灯通信的信号  -----------------------------*/





/*------------------------------  用到的全部定时器初始化  --------------------------------*/

void timer_init(void)
{
  timer_motor_pwm_init();
  timer_ultrasonic_init();

}

